package com.firexxx.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by mmxu6 on 2019-09-02.
 */
@Slf4j
public class JacksonConverter {
    private static ObjectMapper objectMapper;

    public JacksonConverter() {
        this(Jackson2ObjectMapperBuilder.json().build());
    }

    public JacksonConverter(ObjectMapper objectMapper) {
        JacksonConverter.objectMapper = objectMapper;
    }

    public static String toJson(Object value) throws JsonProcessingException {
        return objectMapper.writeValueAsString(value);
    }

    public static String toJsonNullable(Object value) {
        try {
            return toJson(value);
        } catch (JsonProcessingException e) {
            log.warn("JacksonConverter toJson fail", e);
        }
        return null;
    }

    public static <T> T toObject(String content, Class<T> valueType) throws IOException {
        return objectMapper.readValue(content, valueType);
    }

    public static <T> T toObject(String content, JavaType valueType) throws IOException {
        return objectMapper.readValue(content, valueType);
    }

    public static <V> HashMap<String, V> toHashMap(String content, Class<V> valueClasses) throws IOException {
        return toObject(content, parametricType(HashMap.class, String.class, valueClasses));
    }

    public static <K, V> HashMap<K, V> toHashMap(String content, Class<K> keyClasses, Class<V> valueClasses) throws IOException {
        return toObject(content, parametricType(HashMap.class, keyClasses, valueClasses));
    }

    public static <V> List<V> toArrayList(String content, Class<V> valueClasses) throws IOException {
        return toObject(content, parametricType(ArrayList.class, valueClasses));
    }

    public static JavaType parametricType(Class<?> parametrized, Class<?>... parameterClasses) {
        return objectMapper.getTypeFactory().constructParametricType(parametrized, parameterClasses);
    }
}
